/**
 * Copyright (C), 2001-2023, www.bosssof.com.cn
 * FileName: UserServiceImpl
 * Author: WangXin
 * Date: 2024-06-01 11:41:55
 * Description:
 * <p>
 * History:
 * <author> WangXin
 * <time> 2024-06-01 11:41:55
 * <version> 1.0.0
 * <desc> 版本描述
 */
package com.bosssoft.g1.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.bosssoft.g1.common.annotation.page.Pagination;
import com.bosssoft.g1.common.constant.GlobalConstant;
import com.bosssoft.g1.common.data.dto.IdVersion;
import com.bosssoft.g1.common.exception.parse.BusinessException;
import com.bosssoft.g1.common.exception.parse.CustomException;
import com.bosssoft.g1.dto.*;
import com.bosssoft.g1.entity.*;
import com.bosssoft.g1.mapper.*;
import com.bosssoft.g1.query.UserAuthQuery;
import com.bosssoft.g1.query.UserLoginQuery;
import com.bosssoft.g1.query.UserQuery;
import com.bosssoft.g1.service.UserService;
import com.bosssoft.g1.utils.IdGenerator;
import com.bosssoft.g1.vo.IdNameVO;
import com.bosssoft.g1.vo.RoleAuthVO;
import com.bosssoft.g1.vo.RoleVO;
import com.bosssoft.g1.vo.UserAuthVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import tk.mybatis.mapper.entity.Example;
import com.bosssoft.g1.common.exception.code.BizCodeEnum;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @ClassName: UserServiceImpl
 * @Description: 实现UserService接口
 * @Author: Administrator
 * @Date: 2023-03-31 11:41
 **/
@Slf4j
@Service
@Validated
public class UserServiceImpl implements UserService {
    @Autowired
    private  UserMapper userMapper;
    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private PositionMapper positionMapper;

//    @Autowired
//    private CompanyMapper companyMapper;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;


    /**
     * 用户认证方法
     *
     * @param userAuthQuery 包含用户认证信息的DTO
     * @return 认证成功返回User对象，失败返回null
     */
    @Override
    public UserAuthVO authenticate(UserLoginQuery userAuthQuery) {
        // 查询用户
        List<User> users = getUsers(userAuthQuery);

        if (CollectionUtil.isEmpty(users)) {
            return null;
        } else if (users.size() > 1) {
            throw new CustomException("code重复");
        }

        // 获取用户的权限列表
        User user = users.get(0);
        UserAuthVO userVO = new UserAuthVO();

        System.out.println("user " + user.toString());

/*        if (user != null) {
            // 验证密码

            System.out.println("验证密码");
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            if (!bCryptPasswordEncoder.matches(userAuthQuery.getPassword(), user.getPassword())) {
                // 密码不匹配，认证失败
                return null;
            }
        }*/

        BeanUtil.copyProperties(user, userVO);
        System.out.println("getRoleList");
        List<Role> roleList = getRoleList(user.getId());
        List<RoleAuthVO> roleVOList = new ArrayList<>(roleList.size());
        for (Role role : roleList) {
            RoleAuthVO roleVO = new RoleAuthVO();
            BeanUtil.copyProperties(role, roleVO);
            roleVOList.add(roleVO);
        }
        userVO.setRoleList(roleVOList);
        // 用户不存在或密码不匹配，返回null
        System.out.println("userAuthVO" + userVO.toString());

        return userVO;
    }

    private List<Role> getRoleList(Long userId) {
        Example example = new Example(UserRole.class);
        example.createCriteria().andEqualTo("userId", userId);
        List<UserRole> userRoles = userRoleMapper.selectByExample(example);
        System.out.println("--------------UserRole" + userRoles);
        List<Long> userRoleIds = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        example = new Example(Role.class);
        example.createCriteria().andIn("id", userRoleIds);
        List<Role> roles = roleMapper.selectByExample(example);
        System.out.println("--------------roles" + roles);
        return roleMapper.selectByExample(example);
    }


    private List<User> getUsers(UserLoginQuery userAuthQuery) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("code", userAuthQuery.getCode());
        List<User> users = userMapper.selectByExample(example);
        return users;
    }

    /**
     * 添加用户
     */
    @Override
    public Boolean add(@NotNull @Valid UserDTO userDTO) {
        //检查用户的编号是否已经存在
        if(userMapper.userExistByUserCode(userDTO.getCode())){
            log.warn("Role with code {} already exists.", userDTO.getCode());
            throw new BusinessException(String.valueOf(-2L),"该用户编号已存在");
        }

        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setId(idGenerator.snowflakeId());
        user.setCreatedTime(new Date());
        user.setUpdatedTime(new Date());
        user.setVersion(idGenerator.snowflakeId());
        user.setStatus(GlobalConstant.ROW_DATA_STATUS_ACTIVE);
        user.setCompanyId(1337960193258029056L);
        user.setCreatedBy(11L);
        user.setUpdatedBy(11L);
        user.setTenantId(1337940702788714496L);
        System.out.println(user);
        userMapper.insert(user);

        List<Long> roleIds = userDTO.getRoleIds();
        Long userId = user.getId();
        boolean allInserted = true;

        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setCreatedBy(11L);
            userRole.setCreatedTime(new Date());
            userRole.setTenantId(12331L);
            userRole.setId(idGenerator.snowflakeId());
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRole.setVersion(12L);
            boolean inserted = userRoleMapper.insert(userRole) > 0;
            if (!inserted) {
                allInserted = false;
            }
        }

        log.info("test dev-tools");
        return allInserted;
    }


    /**
     * 删除用户
     */
    @Override
    public Boolean remove(@NotNull @Valid Long id) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("id", id);
        List<User> users = userMapper.selectByExample(example);
        if(users.isEmpty()){
            throw new BusinessException(String.valueOf(id),"User not find with id");
        }
        //删除用户角色表
        Example exampleUserRole = new Example(UserRole.class);
        exampleUserRole.createCriteria().andEqualTo("userId",id);
        userRoleMapper.deleteByExample(exampleUserRole);
        //删除用户表
        Example exampleUser = new Example(User.class);
        exampleUser.createCriteria().andEqualTo("id",id);
        int result=userMapper.deleteByExample(exampleUser);

        return result > 0;
    }

    /**
     * 批量删除用户
     */
    @Override
    public Boolean batchRemove(@NotEmpty List<UserDTO> userDTO) {
        boolean result = true;

        for (UserDTO dto : userDTO) {
            Long id = dto.getId();


            // 删除角色用户表相关信息
            Example exampleUserRole = new Example(UserRole.class);
            exampleUserRole.createCriteria().andEqualTo("userId", id);
            userRoleMapper.deleteByExample(exampleUserRole);

            // 删除用户表相关信息
            Example exampleUser = new Example(User.class);
            exampleUser.createCriteria().andEqualTo("id", id);
            Boolean temp = userMapper.deleteByExample(exampleUser) > 0;

            result = result && temp;
        }
        return result;
    }

    /**
     * 通过用户id查询单个用户
     * @param id
     * @return UserDTO
     */
    @Override
    public UserDTO queryUserById(Long id) {
        User user = userMapper.selectByPrimaryKey(id);
        //UserRole userRole=userRoleMapper.selectBy()
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);

        if (user != null) {
            /*// 打印调试信息
            System.out.println("Role from DB: " + role);*/

            // 初始化嵌套对象
            if (userDTO.getCompanyDTO() == null) {
                userDTO.setCompanyDTO(new CompanyDTO());
            }
            if (userDTO.getDepartmentDTO() == null) {
                userDTO.setDepartmentDTO(new DepartmentDTO());
            }
            if (userDTO.getPositionDTO() == null) {
                userDTO.setPositionDTO(new PositionDTO());
            }
//            if (userDTO.getRoleDTO() == null) {
//                userDTO.setRoleDTO(new RoleDTO());
//            }

            Company company = companyMapper.selectByPrimaryKey(user.getCompanyId());
            Department department = departmentMapper.selectByPrimaryKey(user.getDepartmentId());
            //Role role = roleMapper.selectByPrimaryKey(user.getRoleId());
            Position position = positionMapper.selectByPrimaryKey(user.getPositionId());
            // 复制属性
            if (user.getCompanyId() != null) {
                BeanUtils.copyProperties(company, userDTO.getCompanyDTO());
            }
            if (user.getDepartmentId() != null) {
                BeanUtils.copyProperties(department, userDTO.getDepartmentDTO());
            }
            if (user.getPositionId() != null) {
                BeanUtils.copyProperties(position, userDTO.getPositionDTO());
            }
            /*// 打印调试信息
            System.out.println("CompanyDTO: " + userDTO.getCompanyDTO());
            System.out.println("OrganizationDTO: " + userDTO.getOrganizationDTO());
            System.out.println("TenantDTO: " + userDTO.getTenantDTO());*/
        } else {
            // 打印调试信息
            System.out.println("No Role found with id: " + id);
        }
        return userDTO;
    }

    /**
     * 获取所有用户信息
     */
    @Override
    public PageInfo<UserDTO> getAllUsers(PageDTO pageDTO) {
        PageMethod.startPage(pageDTO.getPageNum(),pageDTO.getPageSize());
        System.out.println("page信息"+pageDTO.getPageNum()+" "+pageDTO.getPageSize());
        List<UserDTO> userList=userMapper.getAllUsers();
        return new PageInfo<>(userList);
    }

    /**
     * 分页查询
     *
     * @param username
     * @param password
     * @return true成功 false失败
     */
    @Override
    public Boolean tokenQuery(String username, String password) {
        return null;
    }

/*    @Pagination
    @Override
    public List<UserDTO> getAllUsers(@NotNull @Valid PageDTO pageDTO) {
//        System.out.println("pageInfo");
//        System.out.println(pageDTO.getPageNum());
//        System.out.println(pageDTO.getPageSize());
        PageMethod.startPage(pageDTO.getPageNum(),pageDTO.getPageSize());
        return userMapper.getAllUsers();
    }*/

    @Override
    public PageInfo<UserDTO> searchUser(UserQuery userQuery) {
//        System.out.println("pageInfo");
//        System.out.println(userQuery.getPageNum());
//        System.out.println(userQuery.getPageSize());
        PageMethod.startPage(userQuery.getPageNum(),userQuery.getPageSize());
        List<UserDTO> userList = userMapper.searchUser(userQuery);
        return new PageInfo<>(userList);
    }

    @Override
    public List<IdNameVO> getAllDepartments() {
        List<IdNameVO> idNameVOS = userMapper.getAllDepartments();
        for(IdNameVO idNameVO : idNameVOS){
            idNameVO.setType("1");
        }
        return idNameVOS;
    }

    @Override
    public List<IdNameVO> getAllRoles() {
        List<IdNameVO> idNameVOS = userMapper.getAllRoles();
        for(IdNameVO idNameVO : idNameVOS){
            idNameVO.setType("3");
        }
        return idNameVOS;
    }

    @Override
    public List<IdNameVO> getAllPositions() {
        List<IdNameVO> idNameVOS = userMapper.getAllPositions();
        for(IdNameVO idNameVO : idNameVOS){
            idNameVO.setType("2");
        }
        return idNameVOS;
    }

    @Override
    public Boolean updateUser(UserDTO userDTO) {
        //检查用户的编号是否已经存在
        if(userMapper.userExistByUserCode(userDTO.getCode())){
            log.warn("Role with code {} already exists.", userDTO.getCode());
            throw new BusinessException(String.valueOf(-2L),"该用户编号已存在");
        }

        User user=userMapper.selectByPrimaryKey(userDTO.getId());
        if(user==null){
            throw new BusinessException("User 未找到");
        }
        BeanUtils.copyProperties(userDTO,user);
        user.setCreatedBy(11L);
        user.setVersion(1L);
        user.setStatus(GlobalConstant.ROW_DATA_STATUS_ACTIVE);
        user.setTenantId(1337940702788714496L);
        user.setUpdatedBy(11L);
        user.setUpdatedTime(new Date());
        return userMapper.updateByPrimaryKey(user)>0;
    }

    /**
     * @param ids
     * @return
     */
    @Override
    public List<User> getUserByIds(List<Long> ids) {
        List<User> ans = new ArrayList<>();
        for (Long id : ids) {
            User user = userMapper.selectByPrimaryKey(id);
            if (user!= null) {
                ans.add(user);
            }
        }
        return ans;
    }

    /**
     * @param id
     * @return
     */
    @Override
    public User getUserById(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    /**
     * @param ids
     * @param status
     * @return
     */
    @Override
    public void changeStatus(List<Long> ids, int status) {
        // 用户是启用状态停止
        List<User> users = getUserByIds(ids);
        for (User user : users) {
            user.setStatus((byte) status);
            userMapper.updateByPrimaryKey(user);
        }
    }

    /**
     * 使用tkmybatis批量删除所有user_id在Ids里的UserRole，然后为所有userIds里的user_id增加所有roleIds里的role.
     * @param userIds
     * @param roleIds
     */
    @Override
    public boolean userAssign(List<Long> userIds, List<Long> roleIds) {
        // 批量删除所有 user_id 在 userIds 里的 UserRole
        Example deleteExample = new Example(UserRole.class);
        Example.Criteria deleteCriteria = deleteExample.createCriteria();
        deleteCriteria.andIn("userId", userIds);
        userRoleMapper.deleteByExample(deleteExample);

        int count = insertUserRole(userIds, roleIds, 1L);
        if (count != userIds.size() * roleIds.size()) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 插入userRole表
     * @author YuXingZh
     * @date 2024/06/09 22:37
     *
     * @param userIds
     * @param roleIds
     * @param tenantId
     * @return int
     */
    private int insertUserRole(List<Long> userIds, List<Long> roleIds, Long tenantId) {
        // 为所有 userIds 里的 user_id 增加所有 roleIds 里的 role
        List<UserRole> userRolesToInsert = new ArrayList<>();
        for (Long userId : userIds) {
            for (Long roleId : roleIds) {
                UserRole userRole = new UserRole();
                userRole.setId(idGenerator.snowflakeId());
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                userRole.setTenantId(tenantId);
                userRole.setCreatedBy(tenantId);
                userRole.setCreatedTime(new Date());
                userRole.setVersion(1L);
                userRole.setStatus((byte) 1);
                userRolesToInsert.add(userRole);
            }
        }

        int count = userRoleMapper.insertList(userRolesToInsert);
        return count;
    }

    /**
     * 生成用户角色职位部门树
     * @param id
     * @return
     */
    @Override
    public Map<String,List> getUserRolePositionDepartmentTree(@NotNull Long id){
        Map<String,List> map = new HashMap<>();
        /*map.put("roles",getUserRole(id));
        map.put("positions",getUserRolePosition(id));
        map.put("departments",getUserRoleDepartment(id));*/

        return map;
    }

    /**
     * 根据部门查询用户信息
     * @param pageNum
     * @param pageSize
     * @param id
     * @return
     */
    @Override
    public PageInfo<UserDTO> getUsersByDepartmentId(@NotNull @Valid int pageNum,int pageSize,Long id){
        PageMethod.startPage(pageNum,pageSize);

        List<UserDTO> userList=userMapper.getUsersByDepartmentId(id);
        return new PageInfo<>(userList);
    }

    /**
     * 根据职位id查询用户信息
     * @param pageNum
     * @param pageSize
     * @param id
     * @return
     */
    @Override
    public PageInfo<UserDTO> getUsersByPositionId(@NotNull @Valid int pageNum,int pageSize,Long id){
        PageMethod.startPage(pageNum,pageSize);

        List<UserDTO> userList=userMapper.getUsersByPositionId(id);
        return new PageInfo<>(userList);
    }

    /**
     * 根据角色id查询用户信息
     * @param pageNum
     * @param pageSize
     * @param id
     * @return
     */
    @Override
    public PageInfo<UserDTO> getUsersByRoleId(@NotNull @Valid int pageNum,int pageSize,Long id){
        PageMethod.startPage(pageNum,pageSize);

        List<UserDTO> userList=userMapper.getUsersByRoleId(id);
        return new PageInfo<>(userList);
    }

//    /**
//     * 统一查询角色
//     * @param userQuery
//     * @return RoleDTO
//     */
//    @Override
//    public List<UserDTO> commonQuery(@NotNull UserQuery userQuery) {
//        // 使用 UserQuery 进行查询
//        System.out.println(userQuery);
//        List<User> users = userMapper.selectByName(userQuery.getName());
//        // 将 User 实体转换为 UserDTO
//        return users.stream()
//                .map(this::convertToUserDTO)
//                .collect(Collectors.toList());
//    }
}
